import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

class PersonalFinanceManager {
    private List<Income> incomes = new ArrayList<>();
    private List<Expense> expenses = new ArrayList<>();
6
    private double monthlyBudgetLimit;
    private double spent;

    public PersonalFinanceManager(double monthlyBudgetLimit) {
        this.monthlyBudgetLimit = monthlyBudgetLimit;
        this.spent = 0;
    }

    public void recordIncome(String date, double amount, String category, String note) {
        if (amount <= 0) {
            System.out.println("收入金额必须为正数！");
            return;
        }
        Income income = new Income(date, amount, category, note);
        incomes.add(income);
        System.out.println("收入记录成功！");
    }

    public void recordExpense(String date, double amount, String category, String note) {
        if (amount <= 0) {
            System.out.println("支出金额必须为正数！");
            return;
        }
        Expense expense = new Expense(date, amount, category, note);
        expenses.add(expense);
        spent += amount;
        System.out.println("支出记录成功！");
    }

    public List<Income> getAllIncomes() {
        return incomes;
    }

    public List<Expense> getAllExpenses() {
        return expenses;
    }

    public List<Income> queryIncomes(String startDate, String endDate, String category) {
        List<Income> results = new ArrayList<>();
        for (Income income : incomes) {
            if ((startDate == null || income.getDate().compareTo(startDate) >= 0) &&
                    (endDate == null || income.getDate().compareTo(endDate) <= 0) &&
                    (category == null || income.getCategory().equals(category))) {
                results.add(income);
            }
        }
        return results;
    }

    public List<Expense> queryExpenses(String startDate, String endDate, String category) {
        List<Expense> results = new ArrayList<>();
        for (Expense expense : expenses) {
            if ((startDate == null || expense.getDate().compareTo(startDate) >= 0) &&
                    (endDate == null || expense.getDate().compareTo(endDate) <= 0) &&
                    (category == null || expense.getCategory().equals(category))) {
                results.add(expense);
            }
        }
        return results;
    }

    public void setMonthlyBudget(double budget) {
        this.monthlyBudgetLimit = budget;
        this.spent = 0; // 重置已花费金额
        System.out.println("月度预算设置成功！");
    }

    public double getRemainingBudget() {
        return monthlyBudgetLimit - spent;
    }

    public void displayMonthlyReport() {
        double totalIncome = 0;
        double totalExpense = 0;
        double totalByCategory = 0;
        System.out.println("月度统计报告：");

        System.out.println("总收入：");
        for (Income income : incomes) {
            totalIncome += income.getAmount();
        }
        System.out.println(totalIncome);

        System.out.println("总支出：");
        for (Expense expense : expenses) {
            totalExpense += expense.getAmount();
        }
        System.out.println(totalExpense);

        System.out.println("按类别统计支出：");
        for (Expense expense : expenses) {
            totalByCategory += expense.getAmount();
            System.out.println("类别: " + expense.getCategory() + ", 金额: " + expense.getAmount());
        }

        System.out.println("剩余预算: " + getRemainingBudget());
    }

    public void displayMenu() {
        Scanner scanner = new Scanner(System.in);

        while (true) {
            System.out.println("=================================");
            System.out.println("欢迎使用个人账单管理系统");
            System.out.println("=================================");
            System.out.println("请选择操作：");
            System.out.println("1. 记录收入");
            System.out.println("2. 记录支出");
            System.out.println("3. 查看所有账单");
            System.out.println("4. 查询账单");
            System.out.println("5. 设置月度预算");
            System.out.println("6. 查看月度统计报告");
            System.out.println("7. 退出系统");
            System.out.print("请选择: ");
            int choice = scanner.nextInt();
            scanner.nextLine(); // 清除换行符

            switch (choice) {
                case 1:
                    System.out.print("请输入日期（yyyy-MM-dd）: ");
                    String date = scanner.nextLine();
                    System.out.print("请输入金额: ");
                    double amount = scanner.nextDouble();
                    scanner.nextLine(); // 清除换行符
                    System.out.print("请输入类别: ");
                    String category = scanner.nextLine();
                    System.out.print("请输入备注: ");
                    String note = scanner.nextLine();
                    recordIncome(date, amount, category, note);
                    break;
                case 2:
                    System.out.print("请输入日期（yyyy-MM-dd）: ");
                    date = scanner.nextLine();
                    System.out.print("请输入金额: ");
                    amount = scanner.nextDouble();
                    scanner.nextLine(); // 清除换行符
                    System.out.print("请输入类别: ");
                    category = scanner.nextLine();
                    System.out.print("请输入备注: ");
                    note = scanner.nextLine();
                    recordExpense(date, amount, category, note);
                    break;
                case 3:
                    System.out.println("收入记录:");
                    for (Income income : getAllIncomes()) {
                        System.out.println(income);
                    }
                    System.out.println("支出记录:");
                    for (Expense expense : getAllExpenses()) {
                        System.out.println(expense);
                    }
                    break;
                case 4:
                    System.out.print("请输入开始日期（yyyy-MM-dd，可选）: ");
                    String startDate = scanner.nextLine();
                    System.out.print("请输入结束日期（yyyy-MM-dd，可选）: ");
                    String endDate = scanner.nextLine();
                    System.out.print("请输入类别（可选）: ");
                    category = scanner.nextLine();
                    System.out.println("收入记录:");
                    for (Income income : queryIncomes(startDate, endDate, category)) {
                        System.out.println(income);
                    }
                    System.out.println("支出记录:");
                    for (Expense expense : queryExpenses(startDate, endDate, category)) {
                        System.out.println(expense);
                    }
                    break;
                case 5:
                    System.out.print("请输入月度预算: ");
                    double budget = scanner.nextDouble();
                    setMonthlyBudget(budget);
                    break;
                case 6:
                    displayMonthlyReport();
                    break;
                case 7:
                    System.exit(0);
                    break;
                default:
                    System.out.println("无效的选择，请重新选择！");
            }
        }
    }

    public static void main(String[] args) {
        PersonalFinanceManager manager = new PersonalFinanceManager(5000); // 假设初始月度预算是5000元
        manager.displayMenu();
    }
}

class Income {
    private String date;
    private double amount;
    private String category;
    private String note;

    public Income(String date, double amount, String category, String note) {
        this.date = date;
        this.amount = amount;
        this.category = category;
        this.note = note;
    }

    @Override
    public String toString() {
        return "日期: " + date + ", 金额: " + amount + ", 类别: " + category + ", 备注: " + note;
    }

    public String getDate() {
        return date;
    }

    public double getAmount() {
        return amount;
    }

    public String getCategory() {
        return category;
    }

    public String getNote() {
        return note;
    }
}

class Expense {
    private String date;
    private double amount;
    private String category;
    private String note;

    public Expense(String date, double amount, String category, String note) {
        this.date = date;
        this.amount = amount;
        this.category = category;
        this.note = note;
    }

    @Override
    public String toString() {
        return "日期: " + date + ", 金额: " + amount + ", 类别: " + category + ", 备注: " + note;
    }

    public String getDate() {
        return date;
    }

    public double getAmount() {
        return amount;
    }

    public String getCategory() {
        return category;
    }

    public String getNote() {
        return note;
    }
}